#include "../lib/coreplugin.hpp"
#include "../lib/coreutil.hpp"
#include <boost/thread/thread.hpp>

using namespace pland;

Plugin::Plugin(UserC_Plugin* plugin, void (*wrapup)(UserC_Plugin *), Plugin_Id id)
{
    plugin_ = plugin;
    wrapup_ = wrapup;
    state_ = TERMINATED;
    id_ = id;
    plugin_->setId(id);
}

Plugin::~Plugin()
{
    utill_log(std::string(__FILE__) +" Unloading plugin " + utill_to_string(id_));
    if(state_ != TERMINATED)
        stop();
    wrapup_(plugin_);
}


UserC_Plugin * Plugin::getUserPlugin()
{
    return plugin_;
}


Plugin_Id Plugin::getId()
{
    return id_;
}

bool Plugin::start()
{
    if(state_ == TERMINATED)
    {
        thread_ =  boost::thread(&Plugin::start_, this);
        return true;
    }
    if(state_ == PAUSED)
    {
        state_ = RUNNING;
        return true;
    }
    return false;
}

bool Plugin::stop()
{
    if(state_ == TERMINATED)
        return false;
    while(true)
    {
		state_ = TERMINATED;
		thread_.interrupt();
		boost::system_time timeout=boost::get_system_time() + boost::posix_time::milliseconds(50);
		if(thread_.timed_join(timeout))
			break;
	}
    return true;
}

bool Plugin::pause()
{
    if(state_ != RUNNING)
        return false;
    state_ = PAUSED;
    thread_.interrupt();
    return true;
}

void Plugin::start_()
{
    state_ = RUNNING;
    while(state_ != TERMINATED)
    {
        switch(state_)
        {
        case RUNNING:
            utill_log(std::string(__FILE__) + " Pluggin " + utill_to_string(id_) + " started in thread "+ utill_to_string(boost::this_thread::get_id()));
            try
            {
                plugin_->start();
            }
            catch(boost::thread_interrupted e)
            {
            }
            break;
        case PAUSED:
            boost::this_thread::sleep(boost::posix_time::milliseconds(50));
            break;
        default:
            break;
        }
    }
    if(state_ == RUNNING)
    {
        utill_log(std::string(__FILE__) + " Thread " + utill_to_string(boost::this_thread::get_id()) + " died");
    }
}
